home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / xplatfrm / motxas / do9.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-14  |  12.6 KB  |  645 lines

  1. /*
  2.  *      MC6809 specific processing
  3.  */
  4.  
  5. #define PAGE2    0x10
  6. #define PAGE3    0x11
  7. #define IPBYTE    0x9F    /* extended indirect postbyte */
  8. #define SWI     0x3F
  9.  
  10. /* register names */
  11.  
  12. #define RD    0
  13. #define RX    1
  14. #define RY    2
  15. #define RU    3
  16. #define RS    4
  17. #define RPC    5
  18. #define RA    8
  19. #define RB    9
  20. #define RCC    10
  21. #define RDP    11
  22. #define RPCR    12
  23.  
  24. /* convert tfr/exg reg number into psh/pul format */
  25. int     regs[] = { 6,16,32,64,64,128,0,0,2,4,1,8,0};
  26. int     rcycl[]= { 2,2, 2, 2, 2, 2,  0,0,1,1,1,1,0};
  27.  
  28. /* addressing modes */
  29. #define IMMED   0       /* immediate */
  30. #define IND     1       /* indexed */
  31. #define INDIR   2       /* indirect */
  32. #define OTHER   3       /* NOTA */
  33.  
  34. /*
  35.  *      localinit --- machine specific initialization
  36.  */
  37. localinit()
  38. {
  39. }
  40.  
  41. /*
  42.  *      do_op --- process mnemonic
  43.  *
  44.  *    Called with the base opcode and it's class. Optr points to
  45.  *    the beginning of the operand field.
  46.  */
  47. do_op(opcode,class)
  48. int opcode;    /* base opcode */
  49. int class;    /* mnemonic class */
  50. {
  51.         char    *skip_white();
  52.     int     dist;   /* relative branch distance */
  53.     int     src,dst;/* source and destination registers */
  54.     int     pbyte;  /* postbyte value */
  55.     int     amode;  /* indicated addressing mode */
  56.     int    j;
  57.  
  58.     amode = set_mode();     /* pickup indicated addressing mode */
  59.  
  60.     switch(class){
  61.         case INH:                       /* inherent addressing */
  62.             emit(opcode);
  63.             return;
  64.         case GEN:                       /* general addressing */
  65.             do_gen(opcode,amode);
  66.             return;
  67.         case IMM:                       /* immediate addressing */
  68.             if( amode != IMMED ){
  69.                 error("Immediate Operand Required");
  70.                 return;
  71.                 }
  72.             Optr++;
  73.             eval();
  74.             emit(opcode);
  75.             emit(lobyte(Result));
  76.             return;
  77.         case REL:                       /* short relative branches */
  78.             if( eval() )
  79.                 dist = Result - (Pc+2);
  80.             else dist = -2;
  81.             emit(opcode);
  82.             if( (dist >127 || dist <-128) && Pass==2){
  83.                 error("Branch out of Range");
  84.                 dist = -2;
  85.                 }
  86.             emit(lobyte(dist));
  87.             return;
  88.         case P2REL:                     /* long relative branches */
  89.             eval();
  90.             dist = Result - (Pc+4);
  91.             emit(PAGE2);
  92.             emit(opcode);
  93.             eword(dist);
  94.             return;
  95.         case P1REL:                     /* lbra and lbsr */
  96.             eval();
  97.             dist = Result - (Pc+3);
  98.             emit(opcode);
  99.             eword(dist);
  100.             return;
  101.         case NOIMM:
  102.             if( amode == IMMED ){
  103.                 error("Immediate Addressing Illegal");
  104.                 return;
  105.                 }
  106.             do_gen(opcode,amode);
  107.             return;
  108.         case P2GEN:
  109.             emit(PAGE2);
  110.             if( amode == IMMED ){
  111.                 emit(opcode);
  112.                 Optr++;
  113.                 eval();
  114.                 eword(Result);
  115.                 return;
  116.                 }
  117.             do_gen(opcode,amode);
  118.             return;
  119.         case P3GEN:
  120.             emit(PAGE3);
  121.             if( amode == IMMED ){
  122.                 emit(opcode);
  123.                 Optr++;
  124.                 eval();
  125.                 eword(Result);
  126.                 return;
  127.                 }
  128.             do_gen(opcode,amode);
  129.             return;
  130.         case RTOR:                      /* tfr and exg */
  131.             emit(opcode);
  132.             src = regnum();
  133.             while(alpha(*Optr))Optr++;
  134.             if(src==ERR){
  135.                 error("Register Name Required");
  136.                 emit(0);
  137.                 return;
  138.                 }
  139.             if(*Optr++ != ','){
  140.                 error("Missing comma");
  141.                 emit(0);
  142.                 return;
  143.                 }
  144.             Optr = skip_white(Optr);
  145.             dst = regnum();
  146.             while(alpha(*Optr))Optr++;
  147.             if(dst==ERR){
  148.                 error("Two Register Names Required");
  149.                 emit(0);
  150.                 return;
  151.                 }
  152.             if( src==RPCR || dst==RPCR){
  153.                 error("PCR illegal here");
  154.                 emit(0);
  155.                 return;
  156.                 }
  157.             if( src >=8 && dst <=5 ){
  158.                 error("Register Size Mismatch");
  159.                 src = dst = 0;
  160.                 }
  161.             else if(opcode == 30 && src <=5 && dst >=8) {
  162.                 error("Register Size Mismatch");
  163.                 src = dst = 0;
  164.                 }
  165.             emit( (src<<4)+dst );
  166.             return;
  167.         case INDEXED:                   /* indexed addressing only */
  168.             if( *Optr == '#'){
  169.                 Optr++;         /* kludge city */
  170.                 amode = IND;
  171.                 }
  172.             if( amode != IND ){
  173.                 error("Indexed Addressing Required");
  174.                 return;
  175.                 }
  176.             do_indexed(opcode);
  177.             return;
  178.         case RLIST:                     /* pushes and pulls */
  179.             if( regnum() == ERR ) {
  180.                 error("Register List Required");
  181.                 return;
  182.                 }
  183.             emit(opcode);
  184.             pbyte = 0;
  185.             do{
  186.                                 Optr = skip_white(Optr);
  187.                 j = regnum();
  188.                 if( j == ERR || j==RPCR)
  189.                     error("Illegal Register Name");
  190.                 else if(j==RS && (opcode==52))
  191.                     error("Can't Push S on S");
  192.                 else if(j==RU && (opcode==54))
  193.                     error("Can't Push U on U");
  194.                 else if(j==RS && (opcode==53))
  195.                     error("Can't Pull S from S");
  196.                 else if(j==RU && (opcode==55))
  197.                     error("Can't Pull U from U");
  198.                 else{
  199.                     pbyte |= regs[j];
  200.                     Cycles += rcycl[j];
  201.                     }
  202.                 while(alpha(*Optr)) Optr++;
  203.             }while( *Optr++ == ',' );
  204.             emit(lobyte(pbyte));
  205.             return;
  206.         case P2NOIMM:
  207.             if( amode == IMMED )
  208.                 error("Immediate Addressing Illegal");
  209.             else{
  210.                 emit(PAGE2);
  211.                 do_gen(opcode,amode);
  212.                 }
  213.             return;
  214.         case P2INH:                     /* Page 2 inherent */
  215.             emit(PAGE2);
  216.             emit(opcode);
  217.             return;
  218.         case P3INH:                     /* Page 3 inherent */
  219.             emit(PAGE3);
  220.             emit(opcode);
  221.             return;
  222.         case LONGIMM:
  223.             if( amode == IMMED ){
  224.                 emit(opcode);
  225.                 Optr++;
  226.                 eval();
  227.                 eword(Result);
  228.                 }
  229.             else
  230.                 do_gen(opcode,amode);
  231.             return;
  232.         case GRP2:
  233.             if( amode == IND ){
  234.                 do_indexed(opcode+0x60);
  235.                 return;
  236.                 }
  237.             else if( amode == INDIR){
  238.                 Optr++;
  239.                 emit(opcode + 0x60);
  240.                 emit(IPBYTE);
  241.                 eval();
  242.                 eword(Result);
  243.                 Cycles += 7;
  244.                 if(*Optr == ']'){
  245.                     Optr++;
  246.                     return;
  247.                     }
  248.                 error("Missing ']'");
  249.                 return;
  250.                 }
  251.             eval();
  252.             if(Force_word){
  253.                 emit(opcode+0x70);
  254.                 eword(Result);
  255.                 Cycles += 3;
  256.                 return;
  257.                 }
  258.             if(Force_byte){
  259.                 emit(opcode);
  260.                 emit(lobyte(Result));
  261.                 Cycles += 2;
  262.                 return;
  263.                 }
  264.             if(Result>=0 && Result <=0xFF){
  265.                 emit(opcode);
  266.                 emit(lobyte(Result));
  267.                 Cycles += 2;
  268.                 return;
  269.                 }
  270.             else {
  271.                 emit(opcode+0x70);
  272.                 eword(Result);
  273.                 Cycles += 3;
  274.                 return;
  275.                 }
  276.         case SYS:                       /* system call */
  277.             emit(SWI);
  278.             eval();
  279.             emit(lobyte(Result));
  280.             return;
  281.         default:
  282.             fatal("Error in Mnemonic table");
  283.         }
  284. }
  285.  
  286.  
  287. /*
  288.  *      do_gen --- process general addressing mode stuff
  289.  */
  290. do_gen(op,mode)
  291. int     op;
  292. int     mode;
  293. {
  294.     if( mode == IMMED){
  295.         Optr++;
  296.         emit(op);
  297.         eval();
  298.         emit(lobyte(Result));
  299.         return;
  300.         }
  301.     else if( mode == IND ){
  302.         do_indexed(op+0x20);
  303.         return;
  304.         }
  305.     else if( mode == INDIR){
  306.         Optr++;
  307.         emit(op+0x20);
  308.         emit(IPBYTE);
  309.         eval();
  310.         eword(Result);
  311.         Cycles += 7;
  312.         if(*Optr == ']'){
  313.             Optr++;
  314.             return;
  315.             }
  316.         error("Missing ']'");
  317.         return;
  318.         }
  319.     else if( mode == OTHER){
  320.         eval();
  321.         if(Force_word){
  322.             emit(op+0x30);
  323.             eword(Result);
  324.             Cycles += 3;
  325.             return;
  326.             }
  327.         if(Force_byte){
  328.             emit(op+0x10);
  329.             emit(lobyte(Result));
  330.             Cycles += 2;
  331.             return;
  332.             }
  333.         if(Result>=0 && Result <=0xFF){
  334.             emit(op+0x10);
  335.             emit(lobyte(Result));
  336.             Cycles += 2;
  337.             return;
  338.             }
  339.         else {
  340.             emit(op+0x30);
  341.             eword(Result);
  342.             Cycles += 3;
  343.             return;
  344.             }
  345.         }
  346.     else {
  347.         error("Unknown Addressing Mode");
  348.         return;
  349.         }
  350. }
  351.  
  352. /*
  353.  *      do_indexed --- handle all weird stuff for indexed addressing
  354.  */
  355. do_indexed(op)
  356. int op;
  357. {
  358.     int     pbyte;
  359.     int     j,k;
  360.     int     predec,pstinc;
  361.     int    byte,word;
  362.     char    *p;
  363.  
  364.     Cycles += 2;    /* indexed is always 2+ base cycle count */
  365.     predec=0;
  366.     pstinc=0;
  367.     pbyte=128;
  368.     byte=0;
  369.     word=0;
  370.     emit(op);
  371.     j=regnum();
  372.     if(j==RA){
  373.         Cycles++;
  374.         abd_index(pbyte+6);
  375.         return;
  376.         }
  377.     if(j==RB){
  378.         Cycles++;
  379.         abd_index(pbyte+5);
  380.         return;
  381.         }
  382.     if(j==RD){
  383.         Cycles += 4;
  384.         abd_index(pbyte+11);
  385.         return;
  386.         }
  387.     if(*Optr=='<') {
  388.         byte=1;
  389.         Optr++;
  390.         }
  391.     else if(*Optr=='>') {
  392.         word=1;
  393.         Optr++;
  394.         }
  395.     if(*Optr=='['){
  396.         pbyte |= 0x10;    /* set indirect bit */
  397.         Optr++;
  398.         if( !any((char)']',Optr))
  399.             error("Missing ']'");
  400.         Cycles += 3;    /* indirection takes this much longer */
  401.         }
  402.     Force_word = NO;    /* setup in case eval() not called */
  403.     Force_byte = NO;
  404.     Result = 0;
  405.     if( *Optr != ',' ) {        /* decide whether to call eval() */
  406.         p = Optr;
  407.         while( *p == '-' ) p++;
  408.         if( regnum() == ERR ) {
  409.             eval();
  410.             if( *Optr == ',' ) Optr++;
  411.             else error("Missing comma");
  412.             }
  413.         }
  414.     else Optr++;
  415.     if( byte ) Force_byte++;
  416.     if( word ) Force_word++;
  417.     if( Force_byte && Force_word ) {
  418.         error("Can't force both byte and word");
  419.         Force_byte = 0;
  420.         }
  421.     while(*Optr=='-'){
  422.         predec++;
  423.         Optr++;
  424.         }
  425.     j=regnum();
  426.     while( alpha(*Optr) )Optr++;
  427.     while(*Optr=='+'){
  428.         pstinc++;
  429.         Optr++;
  430.         }
  431.     if(j==RPC || j==RPCR){
  432.         if( pstinc || predec ){
  433.             error("Auto Inc/Dec Illegal on PC");
  434.             return;
  435.             }
  436.         if(j==RPC){
  437.             if(Force_word){
  438.                 emit(pbyte+13);
  439.                 eword(Result);
  440.                 Cycles += 5;
  441.                 return;
  442.                 }
  443.             if(Force_byte){
  444.                 emit(pbyte+12);
  445.                 emit(lobyte(Result));
  446.                 Cycles++;
  447.                 return;
  448.                 }
  449.             if(Result>=-128 && Result <=127){
  450.                 emit(pbyte+12);
  451.                 emit(lobyte(Result));
  452.                 Cycles++;
  453.                 return;
  454.                 }
  455.             else {
  456.                 emit(pbyte+13);
  457.                 eword(Result);
  458.                 Cycles += 5;
  459.                 return;
  460.                 }
  461.             }
  462.         /* PCR addressing */
  463.         if(Force_word){
  464.             emit(pbyte+13);
  465.             eword(Result-(Pc+2));
  466.             Cycles += 5;
  467.             return;
  468.             }
  469.         if(Force_byte){
  470.             emit(pbyte+12);
  471.             emit(lobyte(Result-(Pc+1)));
  472.             Cycles++;
  473.             return;
  474.             }
  475.         k=Result-(Pc+2);
  476.         if( k >= -128 && k <= 127){
  477.             emit(pbyte+12);
  478.             emit(lobyte(Result-(Pc+1)));
  479.             Cycles++;
  480.             return;
  481.             }
  482.         else{
  483.             emit(pbyte+13);
  484.             eword(Result-(Pc+2));
  485.             Cycles += 5;
  486.             return;
  487.             }
  488.         }
  489.     if(predec || pstinc){
  490.         if(Result != 0){
  491.             error("Offset must be Zero");
  492.             return;
  493.             }
  494.         if(predec>2 || pstinc>2){
  495.             error("Auto Inc/Dec by 1 or 2 only");
  496.             return;
  497.             }
  498.         if((predec==1 && (pbyte&0x10) != 0) ||
  499.            (pstinc==1 && (pbyte&0x10) != 0)){
  500.             error("No Auto Inc/Dec by 1 for Indirect");
  501.             return;
  502.             }
  503.         if(predec && pstinc){
  504.             error("Can't do both predecrement & postincrement!");
  505.             return;
  506.             }
  507.         if(predec)
  508.             pbyte += predec+1;
  509.         else if(pstinc)
  510.             pbyte += pstinc-1;
  511.         pbyte += rtype(j);
  512.         emit(pbyte);
  513.         Cycles += 1 + predec + pstinc;
  514.         return;
  515.         }
  516.     pbyte += rtype(j);
  517.     if(Force_word){
  518.         emit(pbyte+0x09);
  519.         eword(Result);
  520.         Cycles += 4;
  521.         return;
  522.         }
  523.     if(Force_byte){
  524.         emit(pbyte+0x08);
  525.         emit(lobyte(Result));
  526.         Cycles++;
  527.         return;
  528.         }
  529.     if(Result==0){
  530.         emit(pbyte+0x04);
  531.         return;
  532.         }
  533.     if((Result >= -16) && (Result <= 15) && ((pbyte&16)==0)){
  534.         pbyte &= 127;
  535.         pbyte += Result&31;
  536.         emit(pbyte);
  537.         Cycles++;
  538.         return;
  539.         }
  540.     if(Result >= -128 && Result <= 127){
  541.         emit(pbyte+0x08);
  542.         emit(lobyte(Result));
  543.         Cycles++;
  544.         return;
  545.         }
  546.     emit(pbyte+0x09);
  547.     eword(Result);
  548.     Cycles += 4;
  549.     return;
  550. }
  551.  
  552.  
  553. /*
  554.  *      abd_index --- a,b or d indexed
  555.  */
  556.  
  557. abd_index(pbyte)
  558. int pbyte;
  559. {
  560.     int     k;
  561.  
  562.     Optr++;
  563.     if( *Optr++ != ',' )
  564.         error("Missing comma");
  565.     k=regnum();
  566.     pbyte += rtype(k);
  567.     emit(pbyte);
  568.     return;
  569. }
  570.  
  571. /*
  572.  *      rtype --- return register type in post-byte format
  573.  */
  574. rtype(r)
  575. int r;
  576. {
  577.     switch(r){
  578.     case RX:        return(0x00);
  579.     case RY:        return(0x20);
  580.     case RU:        return(0x40);
  581.     case RS:        return(0x60);
  582.         }
  583.     error("Illegal Register for Indexed");
  584.     return(0);
  585. }
  586.  
  587. /*
  588.  *      set_mode --- determine addressing mode from operand field
  589.  */
  590. set_mode()
  591. {
  592.     register char *p;
  593.     int k;
  594.  
  595.     if( *Operand == '#' )
  596.         return(IMMED);          /* immediate addressing */
  597.     p = Operand;
  598.     while( !delim(*p) ) {           /* any , before break */
  599.         if( *p == ',')
  600.             return(IND);    /* indexed addressing */
  601.         p++;
  602.         }
  603.     p = Operand;
  604.     if( *p == '>' || *p == '<' ) p++;
  605.     if( *p == '[' ) p++;
  606.     while( *p == '-' ) p++;
  607.     k = regnum();
  608.     if( k==RS || k==RU || k==RX || k==RY || k==RPC || k==RPCR )
  609.          return(IND);  /* indexed addressing */
  610.     if( *Operand == '[')
  611.         return(INDIR);          /* indirect addressing */
  612.     return(OTHER);                  /* NOTA */
  613. }
  614.  
  615. /*
  616.  *      regnum --- return register number of *Optr
  617.  */
  618. regnum()
  619. {
  620.     if( head(Optr,"D" ))return(RD);
  621.     if( head(Optr,"d" ))return(RD);
  622.     if( head(Optr,"X" ))return(RX);
  623.     if( head(Optr,"x" ))return(RX);
  624.     if( head(Optr,"Y" ))return(RY);
  625.     if( head(Optr,"y" ))return(RY);
  626.     if( head(Optr,"U" ))return(RU);
  627.     if( head(Optr,"u" ))return(RU);
  628.     if( head(Optr,"S" ))return(RS);
  629.     if( head(Optr,"s" ))return(RS);
  630.     if( head(Optr,"PC" ))return(RPC);
  631.     if( head(Optr,"pc" ))return(RPC);
  632.     if( head(Optr,"PCR" ))return(RPCR);
  633.     if( head(Optr,"pcr" ))return(RPCR);
  634.     if( head(Optr,"A" ))return(RA);
  635.     if( head(Optr,"a" ))return(RA);
  636.     if( head(Optr,"B" ))return(RB);
  637.     if( head(Optr,"b" ))return(RB);
  638.     if( head(Optr,"CC" ))return(RCC);
  639.     if( head(Optr,"cc" ))return(RCC);
  640.     if( head(Optr,"DP" ))return(RDP);
  641.     if( head(Optr,"dp" ))return(RDP);
  642.     return(ERR);
  643. }
  644.  
  645.